pub mod client;
mod gap;
mod gatt;
pub mod server;

use nrf_softdevice::ble;
use nrf_softdevice::{raw, Softdevice};
use unmp::id::{Id, PrivateId};

const CONN_NUM: u8 = 10;

fn nrf_softdevice_random(buf: &mut [u8]) -> Result<(), getrandom::Error> {
    let sd = unsafe { Softdevice::steal() };
    if let Err(_) = nrf_softdevice::random_bytes(sd, buf) {
        return Err(getrandom::Error::FAILED_RDRAND);
    }
    return Ok(());
}

#[embassy::task]
pub async fn run_softdevice() -> ! {
    let sd: &Softdevice = unsafe { Softdevice::steal() };
    sd.run().await
}

pub fn init_softdevice() {
    let config = nrf_softdevice::Config {
        clock: Some(raw::nrf_clock_lf_cfg_t {
            source: raw::NRF_CLOCK_LF_SRC_RC as u8,
            rc_ctiv: 16,
            rc_temp_ctiv: 2,
            accuracy: 7,
        }),
        conn_gap: Some(raw::ble_gap_conn_cfg_t {
            conn_count: CONN_NUM,
            event_length: 180,
        }),
        gap_role_count: Some(raw::ble_gap_cfg_role_count_t {
            adv_set_count: 1,
            periph_role_count: 5,
            central_role_count: CONN_NUM - 5,
            central_sec_count: 0,
            _bitfield_1: raw::ble_gap_cfg_role_count_t::new_bitfield_1(0),
        }),
        gatts_attr_tab_size: Some(raw::ble_gatts_cfg_attr_tab_size_t { attr_tab_size: 512 }),
        ..Default::default()
    };
    Softdevice::enable(&config);
    getrandom::register_custom_getrandom!(nrf_softdevice_random);
    gatt::init();
}

pub fn get_address() -> ble::Address {
    let sd = unsafe { Softdevice::steal() };
    ble::get_address(sd)
}
pub fn addr2id(addr: &ble::Address) -> Id {
    let mut mac = [0; 7];
    mac[0] = addr.flags;
    mac[1..7].copy_from_slice(&addr.bytes);
    PrivateId::new(&mac).id()
}
